from typing import List, Optional, Dict, Any

from pyexpat.errors import messages
from collections import OrderedDict
import copy

from src import retMes
from sqlalchemy.orm import Session
from src.models import (sys_objects as sysObjectsModels,
                        sys_objects_field as sysObjectsFieldModels,
                        sys_objects_field_rule as sysObjectsFieldRuleModels
                        )
from src.schemas import (sys_objects as sysObjectsSchemas,
                         sys_objects_field as sysObjectsFieldSchemas
                         )
from src.schemas.login_manager import AuthManager
from src import str_utils as strU
from src.services.manages.dicts import dict_list


def get_rules(
        rule_type: Optional[str],
        field_id: Optional[str],
        db: Session,
        auth: AuthManager
):
    api_id = auth.api_id
    rules = db.query(sysObjectsFieldRuleModels.SysObjectsFieldRule).filter(
        sysObjectsFieldRuleModels.SysObjectsFieldRule.api_id == api_id,
        sysObjectsFieldRuleModels.SysObjectsFieldRule.field_id == field_id,
        sysObjectsFieldRuleModels.SysObjectsFieldRule.rule_type == rule_type).all()
    # 把 rule的rule_key与rule_value转换成字典
    rules_dict = {}
    if rules:
        for rule in rules:
            rules_dict[rule.rule_key] = rule.rule_value

    return rules_dict


# 修改 get_fields 函数中的相关部分
def get_fields(alias: Optional[str],
               db: Session,
               auth: AuthManager):
    api_id = auth.api_id
    language = auth.language
    alias_value = None
    data = {}  # 初始化为字典，支持多别名结构
    alias_count = 0
    if alias:
        alias_list = list(OrderedDict.fromkeys([a.strip() for a in alias.split(",") if a.strip()]))

        alias_count = len(alias_list)
        for alias_item in alias_list:
            alias_value = alias_item

            objects = (db.query(sysObjectsModels.SysObjects)
                       .filter(sysObjectsModels.SysObjects.api_id == api_id,
                               sysObjectsModels.SysObjects.alias == alias_value)
                       .order_by(sysObjectsModels.SysObjects.sort)
                       .all())
            if objects:
                for obj in objects:
                    cols_per_row = obj.cols_per_row
                    # print('cols_per_row',cols_per_row)
                    if cols_per_row is None:
                        cols_per_row = 1
                    row_id = 1
                    rows_count = 1
                    col_span_total = 24
                    col_span_used = 0

                    obj_fields = (db.query(sysObjectsFieldModels.SysObjectsField)
                                  .filter(sysObjectsFieldModels.SysObjectsField.api_id == api_id,
                                          sysObjectsFieldModels.SysObjectsField.object_id == obj.id)
                                  .order_by(sysObjectsFieldModels.SysObjectsField.sort)
                                  .all())

                    fields_list = []  # 为当前 alias_value 收集字段
                    field_type= {'type': 'checkbox', 'width': 60}
                    fields_list.append(field_type)
                    field_type = {'type': 'seq', 'title': '序号','width': 60}
                    fields_list.append(field_type)
                    if obj_fields:
                        # 转换为 Schema 对象
                        obj_fields_schemas = [sysObjectsFieldSchemas.SysObjectsFieldAlias.from_orm(field) for field in
                                              obj_fields]
                        for field in obj_fields_schemas:
                            field_dict = strU.model_to_dict(field)
                            if strU.is_not_empty(field_dict.get('dict_id')):
                                field_dict['options'] = dict_list(db, auth, id=field_dict.get('dict_id'))
                            # 获取该字段的验证规则
                            validation_rules = get_rules("validation", field.id, db, auth)

                            # 检查 field.is_null 并相应处理 required 规则

                            if field.is_null is not None and not field.is_null:  # field.is_null 不为空
                                if not validation_rules:
                                    validation_rules = {}
                                # 如果 validation_rules 中不存在 required，则根据 is_null 设置
                                if 'required' not in validation_rules:
                                    validation_rules[
                                        'required'] = not field.is_null  # is_null 为 False 时 required 为 True

                            if validation_rules:
                                field_dict['Validation'] = validation_rules
                            col_span = field.col_span
                            # print('col_span',col_span)
                            # print('col_span_used',col_span_used)
                            # print('cols_per_row',cols_per_row)
                            if strU.is_empty(col_span):
                                col_span = col_span_total // cols_per_row

                            if (col_span == 24 or col_span_used >= 24) and rows_count != 1 and not field.hide:
                                row_id += 1
                                col_span_used = 0
                                # field_dict['row_id'] = row_id
                            else:
                                if rows_count % cols_per_row == 0 and row_id != 1 and not field.hide and col_span_used >= 24:
                                    row_id += 1
                                    col_span_used = 0
                                else:
                                    col_span_used += col_span

                            field_dict['row_id'] = 1  # row_id
                            field_dict['col_span'] = col_span
                            field_dict['title']= field.label
                            if not field.hide:
                                rows_count += 1
                            fields_list.append(field_dict)

                        # 将字段列表添加到对应别名下
                        data[alias_value] = fields_list
                        # 提取 is_filter 为真的字段
                        # 以下操作会把原始资料也会被修改，使用copy深度拷贝
                        # filter_fields_list = [field for field in fields_list if field.get('is_filter')]
                        filter_fields_list = [
                            copy.deepcopy(field) for field in fields_list if field.get('is_filter')
                        ]
                        # 将过滤后的字段列表添加到对应别名下
                        if filter_fields_list:
                            # 将 filter_fields_list 中所有字段的 col_span 设置为 24
                            for field_list in filter_fields_list:
                                field_list['col_span'] = 24
                                field_list['row_id'] = 1

                            data[f"{alias_value}_isFilter"] = filter_fields_list
                        else:
                            data[f"{alias_value}_isFilter"] = []
    if data:
        return retMes.Success(data)
    else:
        message = retMes.Msg(db, api_id, '9601', language).mes()
        return retMes.Error(message, [])
